const vm = require('vm');
const cheerio = require('cheerio');
const logger = require('../../../util/log');
const config = require('../../config/config');
const fileUtil = require('../../../util/fileUtil');
const utils = require('../../../util/utils');
const Const = require('../../../common/const');

let sharedParam = {
    vm: vm,
    htmlString: '',
    dataBuff: '',
    cheerio: cheerio,
    parserInfo: {},
    result: {},
    logger: logger,
    config: config,
    utils: utils,
    Const: Const
};

let _CACHE_PARSER = {};

class parser {

    /**
     * 执行网页解析流程
     */
    static async runCode(type, htmlString) {
        return new Promise((async (resolve, reject) => {

            sharedParam.htmlString = htmlString;

            let codes = await parser.getParsers(type);
            if (!codes || codes.length === 0) {
                reject(`type:[${type}].  Not found parser mapper.`);
                return;
            }
            for (let code of codes) {
                vm.runInNewContext(code, sharedParam);
                let result = sharedParam.result;
                logger.info(`result:${JSON.stringify(result)}`);
                if (result.code === Const._RETCODE_SUCCESS) {
                    logger.info(`Do parser: [${sharedParam.parserInfo.type}] _Index:[${sharedParam.parserInfo.index}] Success..  `);
                    resolve(result);
                    break;
                } else {
                    logger.err(`Do Parser: [${sharedParam.parserInfo.type}] _Index:[${sharedParam.parserInfo.index}] Failed... Retry`)
                }
            }
            reject(`All Parser Execute Failed.`)
        }))
    }

    /**
     * 获取解析器代码
     */
    static async getParsers(type) {
        logger.info(`Get Parsers Type:[${type}]`)
        let parserPath = await utils.loadParserPath(type);
        let parserCodes = _CACHE_PARSER[parserPath];
        if (parserCodes && parserCodes.length !== 0) {
            logger.info(`Type:[${type}] Find in Cache. Length:[${parserCodes.length}]`);
            return parserCodes;
        }
        logger.info(`Read Parser Dir: [${parserPath}]`);
        parserCodes = await fileUtil.readDirFileContent(parserPath);
        logger.info(`Type:[${type}]  Parsers:${parserCodes.length}`);
        _CACHE_PARSER[parserPath] = parserCodes;
        return parserCodes;
    }

}

module.exports = parser;
